package com.ming.mingbase.base.dao.impl;

import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.annotation.Resource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.transform.Transformers;
import org.springframework.orm.hibernate4.HibernateTemplate;
import org.springframework.orm.hibernate4.support.HibernateDaoSupport;

import com.ming.mingbase.base.dao.IBaseDao;
import com.ming.mingbase.base.exeption.BaseException;
import com.ming.mingbase.base.util.Page;

@SuppressWarnings({ "unchecked" })
public class BaseDao extends HibernateDaoSupport implements IBaseDao {
	@Resource(name = "sqlSessionFactory")
	public SqlSessionFactory sqlSessionFactory;
	public SQLQuery query;

	public <T> boolean add(T entity) throws BaseException {
		beginTransaction();
		boolean result = false;
		Serializable io = this.getHibernateTemplate().save(entity);
		if (io != null) {
			result = true;
		}
		commitTransaction();
		return result;
	}

	public <T> Integer addAndGetIdInteger(T entity) throws BaseException {
		beginTransaction();
		Integer result = null;
		result = (Integer) this.getHibernateTemplate().save(entity);
		commitTransaction();
		return result;
	}

	public <T> String addAndGetIdString(T entity) throws BaseException {
		beginTransaction();
		String result = null;
		result = (String) this.getHibernateTemplate().save(entity);
		commitTransaction();
		return result;
	}

	public <T> boolean delete(T entity) throws BaseException {
		beginTransaction();
		boolean result = false;
		try {
			this.getHibernateTemplate().delete(entity);
			return false;
		} catch (Exception e) {
			new BaseException(e);
		}
		commitTransaction();
		return result;
	}

	public boolean delete(String sql) throws BaseException {
		boolean result = true;
		int re = executeBySql(sql);
		if (re < 0) {
			result = false;
		}
		return result;
	}

	public void batchDel(String sql, String[] ids) throws BaseException {
		beginTransaction();
		SQLQuery query = currentSession().createSQLQuery(sql);
		query.setParameterList("ids", ids);
		query.executeUpdate();
		commitTransaction();
	}

	public int executeBySql(String sql) throws BaseException {
		beginTransaction();
		int result = 0;
		result = currentSession().createSQLQuery(sql).executeUpdate();
		commitTransaction();
		return result;
	}

	public <T> boolean edit(T entity) throws BaseException {
		beginTransaction();
		boolean result = false;
		try {
			this.getHibernateTemplate().update(entity);
			result = true;
		} catch (Exception e) {
			result = false;
			throw new BaseException(e);
		}
		commitTransaction();
		return result;
	}

	public int editBySql(String sql) throws BaseException {
		return executeBySql(sql);
	}

	public <T> T getById(Class<T> entity, Serializable id) throws BaseException {
		T ety = null;
		try {
			beginTransaction();
			ety = (T) this.getHibernateTemplate().get(entity, id);
			commitTransaction();
		} catch (Exception e) {
			throw new BaseException(e);
		}
		return ety;
	}

	public <T> T getBySql(Class<T> entity, String sql) throws BaseException {
		beginTransaction();
		T t = (T) currentSession().createSQLQuery(sql).addEntity(entity)
				.uniqueResult();
		// T t = (T) currentSession().createSQLQuery(sql)
		// .setResultTransformer(Transformers.aliasToBean(entity))
		// .uniqueResult();
		commitTransaction();
		return t;
	}

	public <T> T getBySql(Class<T> entity, String sql,
			Map<String, Object> searchValue) throws BaseException {
		beginTransaction();
		T t = null;
		SQLQuery query = currentSession().createSQLQuery(sql).addEntity(entity);
		// Query query = currentSession().createSQLQuery(sql)
		// .setResultTransformer(Transformers.aliasToBean(entity));
		if (searchValue != null && searchValue.size() > 0) {
			for (Entry<String, Object> entry : searchValue.entrySet()) {
				query.setParameter(entry.getKey(), entry.getValue());
			}
			t = (T) query.uniqueResult();
		} else {
			t = (T) query.list().get(0);
		}
		commitTransaction();
		return t;
	}

	public <T> T getBySqlVO(Class<T> entity, String sql,
			Map<String, Object> searchValue) throws BaseException {
		beginTransaction();
		T t = null;
		// SQLQuery query =
		// currentSession().createSQLQuery(sql).addEntity(entity);
		Query query = currentSession().createSQLQuery(sql)
				.setResultTransformer(Transformers.aliasToBean(entity));
		if (searchValue != null && searchValue.size() > 0) {
			for (Entry<String, Object> entry : searchValue.entrySet()) {
				query.setParameter(entry.getKey(), entry.getValue());
			}
			t = (T) query.uniqueResult();
		} else {
			t = (T) query.list().get(0);
		}
		commitTransaction();
		return t;
	}

	public <T> T getById(Class<T> entity, String id) throws BaseException {
		beginTransaction();
		T t = this.getHibernateTemplate().get(entity, id);
		commitTransaction();
		return t;
	}

	public <T> T getById(Class<T> entity, Integer id) throws BaseException {
		beginTransaction();
		T t = this.getHibernateTemplate().get(entity, id);
		commitTransaction();
		return t;
	}

	public <T> List<T> findBySql(Class<T> entity, String sql)
			throws BaseException {
		beginTransaction();
		List<T> ts = currentSession().createSQLQuery(sql).addEntity(entity)
				.list();
		commitTransaction();
		return ts;
	}

	public <T> List<T> findBySql(Class<T> entity, String sql,
			Map<String, Object> searchValue) throws BaseException {
		beginTransaction();
		List<T> t = null;
		SQLQuery query = currentSession().createSQLQuery(sql).addEntity(entity);
		if (searchValue != null && searchValue.size() > 0) {
			for (Entry<String, Object> entry : searchValue.entrySet()) {
				query.setParameter(entry.getKey(), entry.getValue());
			}
		}
		t = query.list();
		commitTransaction();
		return t;
	}

	public <T> List<T> getList(Class<T> entity) throws BaseException {
		List<T> list = null;
		try {
			currentSession().getTransaction().begin();
			list = (List<T>) this.getHibernateTemplate().findByCriteria(
					DetachedCriteria.forClass(entity));
			currentSession().getTransaction().commit();
		} catch (Exception e) {
			throw new BaseException(e);
		}
		return list;
	}

	public <T> List<T> getList(Class<T> entity, String sql,
			Map<String, Object> searchValue) throws BaseException {
		beginTransaction();
		List<T> t = null;
		SQLQuery query = currentSession().createSQLQuery(sql).addEntity(entity);
		if (searchValue != null && searchValue.size() > 0) {
			for (Entry<String, Object> entry : searchValue.entrySet()) {
				query.setParameter(entry.getKey(), entry.getValue());
			}
		}
		t = query.list();
		commitTransaction();
		return t;
	}

	// 分页查询
	public <T> Page getByPage(Class<T> entity, String querySql,
			String queryCountSql, Map<String, Object> searchValue, Page page)
			throws BaseException {
		beginTransaction();
		SQLQuery countQuery = currentSession().createSQLQuery(queryCountSql);
		if (searchValue != null && searchValue.size() > 0) {
			for (Entry<String, Object> entry : searchValue.entrySet()) {
				countQuery.setParameter(entry.getKey(), entry.getValue());
			}
		}
		countQuery.uniqueResult();
		String count = countQuery.uniqueResult().toString();
		page.setItemCount(Integer.parseInt(count));
		SQLQuery sqlQuery = currentSession().createSQLQuery(querySql)
				.addEntity(entity);
		if (searchValue != null && searchValue.size() > 0) {
			for (Entry<String, Object> entry : searchValue.entrySet()) {
				sqlQuery.setParameter(entry.getKey(), entry.getValue());
			}
		}
		sqlQuery.setFirstResult(page.getItemStart());
		sqlQuery.setMaxResults(page.getPageSize());
		page.setPageData(sqlQuery.list());
		getHibernateTemplate().flush();
		commitTransaction();
		return page;
	}

	// 分页查询Vo
	public <T> Page getByPageVO(Class<T> entity, String querySql,
			String queryCountSql, Map<String, Object> searchValue, Page page)
			throws BaseException {
		beginTransaction();
		SQLQuery countQuery = currentSession().createSQLQuery(queryCountSql);
		if (searchValue != null && searchValue.size() > 0) {
			for (Entry<String, Object> entry : searchValue.entrySet()) {
				countQuery.setParameter(entry.getKey(), entry.getValue());
			}
		}
		countQuery.uniqueResult();
		String count = countQuery.uniqueResult().toString();
		page.setItemCount(Integer.parseInt(count));
		SQLQuery sqlQuery = (SQLQuery) currentSession()
				.createSQLQuery(querySql).setResultTransformer(
						Transformers.aliasToBean(entity));
		if (searchValue != null && searchValue.size() > 0) {
			for (Entry<String, Object> entry : searchValue.entrySet()) {
				sqlQuery.setParameter(entry.getKey(), entry.getValue());
			}
		}
		sqlQuery.setFirstResult(page.getItemStart());
		sqlQuery.setMaxResults(page.getPageSize());
		page.setPageData(sqlQuery.list());
		getHibernateTemplate().flush();
		commitTransaction();
		return page;
	}

	public Session session() {
		return currentSession();
	}

	public HibernateTemplate getTemplate() {
		return getHibernateTemplate();
	}

	/**
	 * 开启事务
	 */
	public void beginTransaction() {
		currentSession().getTransaction().begin();
	}

	/**
	 * 提交事务
	 */
	public void commitTransaction() {
		currentSession().getTransaction().commit();
	}

	public SQLQuery PrepareSql(String sql) throws BaseException {
		beginTransaction();
		return query = currentSession().createSQLQuery(sql);
	}

	public void preValue(String key, Object vlaue) throws BaseException {
		query.setParameter(key, vlaue);
	}

	public void executeSql() throws BaseException {
		query.executeUpdate();
		commitTransaction();
	}
}
